package spittr;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.core.JmsOperations;
import org.springframework.jms.core.JmsTemplate;
import spittr.alerts.AlertService;
import spittr.alerts.AlertServiceImpl;
import spittr.alerts.SpittleAlertHandler;

import javax.jms.ConnectionFactory;
import javax.jms.Destination;

@EnableJms
@Configuration
public class config {

    /*
    在异步消息中有两个主要的概念：
    消息代理（message broker） 和目的地（destination）。
    当一个应用发送消息时， 会将消息交给一个消息代理。
    消息代理可以确保消息被投递到指定的目的地，
    同时解放发送者， 使其能够继续进行其他的业务。

    尽管不同的消息系统会提供不同的消息路由模式，
    但是有两种通用的目的地：
    队列（queue） 和主题（topic）。
    每种类型都与特定的消息模型相关联，
    分别是点对点模型（队列）和发布/订阅模型（主题）。

    在点对点模型中， 每一条消息都有一个发送者和一个接收者。
    当消息代理得到消息时， 它将消息放入一个队列中。
    当接收者请求队列中的下一条消息时，
    消息会从队列中取出， 并投递给接收者。
    因为消息投递后会从队列中删除，
    这样就可以保证消息只能投递给一个接收者。

    在发布—订阅消息模型中， 消息会发送给一个主题。
    与队列类似， 多个接收者都可以监听一个主题。
    但是， 与队列不同的是， 消息不再是只投递给一个接收者，
    而是主题的所有订阅者都会接收到此消息的副本。

    异步消息相对同步通信的优点：
    无需等待、面向消息和解耦、位置独立、确保投递
    */


    @Bean
    public ConnectionFactory connectionFactory(){//创建连接工厂
        ActiveMQConnectionFactory cf=new ActiveMQConnectionFactory();
        cf.setTrustAllPackages(true);
        //cf.setBrokerURL("tcp://localhost:61616");//默认
        return cf;
    }


    //声明ActiveMQ消息目的地
    @Bean
    public Destination queue(){
        Destination destination=new ActiveMQQueue("spittle.alert.queue");//接收一个就结束
        // destination=new ActiveMQTopic("spittle.alert.topic");//不断等待消息
        return destination;
    }

    /*@Bean
    public MessageConverter messageConverter(){
        return new MappingJackson2MessageConverter();
    }
    */

    @Bean
    public JmsOperations jmsTemplate(ConnectionFactory cf,Destination dest/*,MessageConverter mc*/){
        JmsTemplate jmsTemplate=new JmsTemplate(cf);//设置连接工厂

        // 如果已经存在该名称的队列或主题的话， 就会使用已有的。
        // 如果尚未存在的话，将会创建一个新的目的地（通常会是队列）。
        //jmsTemplate.setDefaultDestinationName("spittle.alert.queue");

        jmsTemplate.setDefaultDestination(dest);//设置默认目的地
        //jmsTemplate.setMessageConverter(mc);//设置消息转换器，默认为SimpleMessageConverter
        return jmsTemplate;
    }

    @Bean
    public AlertService alertService(JmsOperations jmsOperations){
        return new AlertServiceImpl(jmsOperations);
    }

    @Bean
    public SpittleAlertHandler spittleAlertHandler(){
        return new SpittleAlertHandler();
    }



    @Bean
    public JmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory cf){
        DefaultJmsListenerContainerFactory jlcf=new DefaultJmsListenerContainerFactory();
        jlcf.setConnectionFactory(cf);
        return jlcf;
    }
}
